package dao

import (
	"gitee.com/huangxinbo/xcas/internal/app/base"
	"gitee.com/huangxinbo/xcas/internal/model/db_model"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type VerificationDAO struct {
	base *base.Base
}

func NewVerificationDAO(base *base.Base) *VerificationDAO {
	return &VerificationDAO{
		base: base,
	}
}

func (d *VerificationDAO) Create(ctx *gin.Context, verification *db_model.Verification) error {
	if err := d.base.Db.WithContext(ctx).Create(verification).Error; err != nil {
		d.base.Logger.Error("Failed to create verification", zap.Error(err))
		return err
	}
	return nil
}

func (d *VerificationDAO) GetByID(ctx *gin.Context, id string) (*db_model.Verification, error) {
	var verification db_model.Verification
	if err := d.base.Db.WithContext(ctx).First(&verification, "id = ?", id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		d.base.Logger.Error("Failed to get verification by ID", zap.String("id", id), zap.Error(err))
		return nil, err
	}
	return &verification, nil
}

func (d *VerificationDAO) GetByIdentifierAndType(ctx *gin.Context, identifier string, verificationType db_model.VerificationType) (*db_model.Verification, error) {
	var verification db_model.Verification
	if err := d.base.Db.WithContext(ctx).Where("identifier = ? AND type = ?", identifier, verificationType).
		Order("created_at DESC").
		First(&verification).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		d.base.Logger.Error("Failed to get verification by identifier and type",
			zap.String("identifier", identifier),
			zap.Int16("type", int16(verificationType)),
			zap.Error(err))
		return nil, err
	}
	return &verification, nil
}

func (d *VerificationDAO) Delete(ctx *gin.Context, id string) error {
	if err := d.base.Db.WithContext(ctx).Delete(&db_model.Verification{}, "id = ?", id).Error; err != nil {
		d.base.Logger.Error("Failed to delete verification", zap.String("id", id), zap.Error(err))
		return err
	}
	return nil
}

func (d *VerificationDAO) DeleteExpired(ctx *gin.Context) error {
	if err := d.base.Db.WithContext(ctx).Where("expired_at < NOW()").Delete(&db_model.Verification{}).Error; err != nil {
		d.base.Logger.Error("Failed to delete expired verifications", zap.Error(err))
		return err
	}
	return nil
}
